<template>
    <div class="GameBox">
        <div class="top">
            <div
                v-for="(item, index) in levelArr"
                :key="index"
                @click="handClickLevel(item.value)"
                :class="{activeLevel: levelValue==item.value, levelItem: true}"
            >{{ item.label }}</div>
        </div>

        <div class="game-box">
            <div v-for="(rows,index) in gameArr" :key="index" class="rows">
                <div
                    v-for="(item,ins) in rows" :key="ins"
                    class="item-box"
                    :style="{width: `${levelData.boxWidth}px`, height: `${levelData.boxHeight}px` }"
                    @click="handleClickChange(index, ins)">
                    <span v-if="item.number!=levelData.row*levelData.col">{{ item.number }}</span>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    name: 'GameBox',
    data() {
        return {
            score: 0,
            bestScore: 0,

            gameArr: [],
            levelArr: [
                {
                    label: '3X3',
                    value: 1,
                    data: { row: 3, col: 3, boxWidth: 160, boxHeight: 160, resetNum: 60 },
                },
                {
                    label: '4X4',
                    value: 2,
                    data: { row: 4, col: 4, boxWidth: 140, boxHeight: 140, resetNum: 100 },
                },
                {
                    label: '6X6',
                    value: 3,
                    data: { row: 6, col: 6, boxWidth: 120, boxHeight: 120, resetNum: 150 },
                },
                {
                    label: '8X8',
                    value: 4,
                    data: { row: 8, col: 8, boxWidth: 90, boxHeight: 90, resetNum: 200 },
                },
                {
                    label: '10X10',
                    value: 5,
                    data: { row: 10, col: 10, boxWidth: 72, boxHeight: 72, resetNum: 300 },
                },
            ],
            // 当前等级
            levelValue: 1,
            levelData: {},

            dirArr: ['top', 'bottom', 'left', 'right']
        }
    },
    watch: {
        levelValue: {
            handler(newVal, oldVal) {
                let index = this.levelArr.findIndex(item => item.value == newVal)
                if(index>=0) {
                    this.levelData = { ...this.levelArr[index]?.data }
                    this.initGameBOX()
                }
            },
            immediate: true
        }
    },
    created() {
        this.levelValue = sessionStorage.getItem('levelValue') || this.levelValue
        this.initGameBOX()
    },
    methods: {
        handClickLevel(value) {
            this.levelValue = value
            sessionStorage.setItem('levelValue', value)
        },
        initGameBOX() {
            let { row, col } = this.levelData
            this.gameArr = []
            for(let i=0; i<row; i++) {
                let arr = []
                for(let j=0; j<col; j++) {
                    arr.push({x: i, y: j, number: i*row+j+1})
                }
                this.gameArr.push(arr)
            }

            this.resetGameBOX()
        },
        resetGameBOX() {
            // 随机打乱
            for(let i = 0; i<(this.levelData?.resetNum || 100); i++) {
                let dirNum = this.randomNum(4)
                this.chnagePosition(this.dirArr[dirNum])
            }
        },
        randomNum(num) {
            // 向下取整
            return Math.floor(Math.random()*num)  // [0, num-1]
        },
        findBlankXY() {
            let { row, col } = this.levelData
            // 遍历每一个元素
            for(let i=0; i<row; i++) {
                for(let j=0; j<col; j++) {
                    let { x, y } = this.gameArr[i][j]
                    if(x==(row-1) && y==(col-1)) {
                        return { x: i, y: j}
                    }
                }
            }
            return { x: -1, y: -1}
        },
        // 交换
        exchange(x,y,i,j) {
            let midObj = {...this.gameArr[x][y]}
            // this.gameArr[x][y] = {...this.gameArr[i][j]}
            this.$set(this.gameArr[x], y, {...this.gameArr[i][j]})
            this.$set(this.gameArr[i], j, {...midObj})
        },
        chnagePosition(direction="top") {
            let { x, y } = this.findBlankXY()
            if(direction=="top") {
                let i = x-1, j = y
                if(i>=0) {
                    this.exchange(x,y,i,j)
                }
            }
            else if(direction=="bottom"){
                let i = x+1, j = y
                if(i<this.levelData.row) {
                    this.exchange(x,y,i,j)
                }
            }
            else if(direction=="left"){
                let i = x, j = y-1
                if(j>=0) {
                    this.exchange(x,y,i,j)
                }
            }
            else if(direction=="right"){
                let i = x, j = y+1
                if(j<this.levelData.col) {
                    this.exchange(x,y,i,j)
                }
            }
        },
        handleClickChange(xx, yy) {
            // 判断四个方向上是不是空白格
            let flag = 1
            if(xx-1>=0 && flag) {
                let { x, y } = this.gameArr[xx-1][yy]
                // 上面是空白格
                if(x==(this.levelData.row-1) && y==(this.levelData.col-1)) {
                    flag = 0
                    this.exchange(xx-1, yy, xx, yy)
                }
            }
            if(xx+1<this.levelData.row && flag) {
                let { x, y } = this.gameArr[xx+1][yy]
                if(x==(this.levelData.row-1) && y==(this.levelData.col-1)) {
                    flag = 0
                    this.exchange(xx+1, yy, xx, yy)
                }
            }
            if(yy-1>=0 && flag) {
                let { x, y } = this.gameArr[xx][yy-1]
                if(x==(this.levelData.row-1) && y==(this.levelData.col-1)) {
                    flag = 0
                    this.exchange(xx, yy-1, xx, yy)
                }
            }
            if(yy+1<this.levelData.col && flag) {
                let { x, y } = this.gameArr[xx][yy+1]
                if(x==(this.levelData.row-1) && y==(this.levelData.col-1)) {
                    flag = 0
                    this.exchange(xx, yy+1, xx, yy)
                }
            }

            setTimeout(() => {
                let isOver = this.gameOver()
                if(isOver) {
                    alert('游戏结束')
                    location.reload()
                }
            })
        },
        // 判断游戏结束
        gameOver() {
            let { row, col } = this.levelData
            // 遍历每一个元素
            for(let i=0; i<row; i++) {
                for(let j=0; j<col; j++) {
                    let { x, y } = this.gameArr[i][j]
                    if(i!=x || j!=y) {
                        return false
                    }
                }
            }
            return true
        }
    }
}
</script>

<style scoped lang="scss">
.GameBox {
    margin: 30px auto;

    display: flex;
    flex-wrap: wrap;
    justify-content: center;

    .top {
        width: 100%;
        display: flex;
        justify-content: center;
        padding: 0 10px;
        margin: 10px 0 30px;

        .levelItem {
            display: inline-block;
            margin: 0 10px;
            padding: 10px 20px;
            background-color: gray;
            color: #fff;
            border-radius: 10px;
        }
        .activeLevel {
            background-color: green;
        }
    }

    .game-box {
        display: inline-block;
        background-color: #f0ecde;
        border: 2px solid #888;

        .rows {
            display: flex;
            .item-box {
                // width: 150px;
                // height: 150px;
                border: 2px solid #888;
                
                display: flex;
                align-items: center;
                justify-content: center;

                span {
                    font-size: 36px;
                }
            }
        }
        
    }
}
</style>
